
// author: niXman
// e-mail: i.nixman@gmail.com
// date: 28.05.2011
//
//
// Boost Software License - Version 1.0 - August 17th, 2003
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#include <iostream>
#include <netclasses/server.hpp>

#include "../tests_config.hpp"

struct global_context;

/***************************************************************************/

struct server_impl: boost::enable_shared_from_this<server_impl> {
   server_impl(netclasses::socket_ptr socket, global_context& gc)
      :socket(socket),
      gc(gc)
   {}

   void start() {
      socket->async_read(1, shared_from_this(), &server_impl::readed);
   }

   void readed(const boost::system::error_code& e, boost::shared_array<char> arr, size_t rd) {
      if ( !e ) {
         socket->async_write(arr, rd, shared_from_this(), &server_impl::writen);
      } else {
         std::cout << "error: " << e.message() << std::endl;
      }
   }
   void writen(const boost::system::error_code&, boost::shared_array<char>, size_t) {
      socket->async_read(1, shared_from_this(), &server_impl::readed);
   }

private:
   netclasses::socket_ptr socket;
   global_context& gc;
};

struct global_context: netclasses::global_context_base {
};

/***************************************************************************/

bool on_connect_handler(const boost::asio::ip::tcp::endpoint& ep) {
   std::cout << "new connection from: " << ep.address().to_string() << ":" << ep.port() << std::endl;
   return true;
}

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      global_context gc;

      netclasses::server<global_context, server_impl> server(
         gc,
         ios,
         config::ip,
         config::port,
         &on_connect_handler
      );
      server.start();
      ios.run();
   } catch ( const std::exception& e ) {
      std::cout << "(exception) " << e.what() << std::endl;
   }
}

/***************************************************************************/
